using System.ComponentModel;
using System.Threading;
using Microsoft.Practices.Unity;

namespace StockTraderRI.Infrastructure.Messaging
{
    public class InMemoryMessageBus : IMessageBus
    {
        private readonly IUnityContainer container;
        private readonly SynchronizationContext threadContext;

        public InMemoryMessageBus(IUnityContainer container)
        {
            this.container = container;
            threadContext = AsyncOperationManager.SynchronizationContext;
        }

        public void Publish(object message)
        {
            threadContext.Post(state => DispatchMessage(message), null);
        }

        private void DispatchMessage(object message)
        {
            var handlerType = typeof (IHandler<>);
            handlerType = handlerType.MakeGenericType(message.GetType());

            var handleMethod = handlerType.GetMethod("Handle");

            var handlers = container.ResolveAll(handlerType);
            foreach (var handler in handlers)
            {
                handleMethod.Invoke(handler, new[] {message});
            }
        }
    }
}